﻿/*
 * Copyright (C) 2011 Kamran Zafar
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * */

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace org.kamranzafar.hotfusion
{
	public class StubGenerator
	{
		private Settings extractorSettings;
		
		public StubGenerator(Settings extractorSettings){
			this.extractorSettings = extractorSettings;
		}
		
		public String generate(List<BindEntry> files){
			String extractorSource=System.Text.UTF8Encoding.UTF8.GetString(hotfusion.Properties.Resources.Extractor);

			extractorSource=extractorSource.Replace("//${EXTRACTOR_SIGN}", buildExtractorSignature());
			extractorSource=extractorSource.Replace("//${POPULATE_HASH}", buildFileSettings(files));
			
			//System.Windows.Forms.MessageBox.Show(extractorSource);
			
			return extractorSource;
		}
		
		private String buildFileSettings(List<BindEntry> files){
			StringBuilder codeBuilder=new StringBuilder();

			for(int i=0;i<files.Count;i++){
				codeBuilder.Append("BindEntry be"+i+"=new BindEntry();\n");
				switch (files[i].Type) {
					case 1:
						codeBuilder.Append("BindEntry.FileEntry fs"+i+"=new BindEntry.FileEntry();\n");
						codeBuilder.Append("fs"+i+".FileName=\""+fixPath(files[i].FilesEntry.FileName.ToString().ToLower())+"\";\n");
						codeBuilder.Append("fs"+i+".Compress="+files[i].FilesEntry.Compress.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".Encrypt="+files[i].FilesEntry.Encrypt.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".Passphrase=\""+files[i].FilesEntry.Passphrase+"\";\n");
						codeBuilder.Append("fs"+i+".DestinationPath=\""+fixPath(files[i].FilesEntry.DestinationPath)+"\";\n");
						codeBuilder.Append("fs"+i+".AddToStartup="+files[i].FilesEntry.AddToStartup.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".RandomlyRename="+files[i].FilesEntry.RandomlyRename.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".RenameFileTo=\""+files[i].FilesEntry.RenameFileTo+"\";\n");
						codeBuilder.Append("fs"+i+".RunOnExtract="+files[i].FilesEntry.RunOnExtract.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".AddToPath="+files[i].FilesEntry.AddToPath.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".RunParams=\""+files[i].FilesEntry.RunParams+"\";\n");
						codeBuilder.Append("fs"+i+".KeyType="+files[i].FilesEntry.KeyType+";\n");
						codeBuilder.Append("fs"+i+".RegKey=\""+files[i].FilesEntry.RegKey+"\";\n");
						codeBuilder.Append("fs"+i+".RandomKey="+files[i].FilesEntry.RandomKey.ToString().ToLower()+";\n");
						codeBuilder.Append("fs"+i+".RandomKey="+files[i].FilesEntry.RandomKey.ToString().ToLower()+";\n");
						codeBuilder.Append("be"+i+".Type=1;\n");
						codeBuilder.Append("be"+i+".FilesEntry=fs"+i+";\n");
						break;
					case 3:
						codeBuilder.Append("BindEntry.CommandEntry ce"+i+"=new BindEntry.CommandEntry();\n");
						codeBuilder.Append("ce"+i+".CommandName=\""+files[i].CmdEntry.CommandName+"\";\n");
						codeBuilder.Append("ce"+i+".CommandParam=\""+files[i].CmdEntry.CommandParam+"\";\n");
						codeBuilder.Append("ce"+i+".RunInBackground="+files[i].CmdEntry.RunInBackground.ToString().ToLower()+";\n");
						codeBuilder.Append("be"+i+".Type=3;\n");
						codeBuilder.Append("be"+i+".CmdEntry=ce"+i+";\n");
						break;
					case 4:
						codeBuilder.Append("BindEntry.EnvironmentEntry ee"+i+"=new BindEntry.EnvironmentEntry();\n");
						codeBuilder.Append("ee"+i+".VarName=\""+files[i].EnvEntry.VarName+"\";\n");
						codeBuilder.Append("ee"+i+".VarValue=\""+files[i].EnvEntry.VarValue+"\";\n");
						codeBuilder.Append("ee"+i+".Type="+files[i].EnvEntry.Type+";\n");
						codeBuilder.Append("be"+i+".Type=4;\n");
						codeBuilder.Append("be"+i+".EnvEntry=ee"+i+";\n");
						break;
					case 5:
						codeBuilder.Append("BindEntry.RegistryEntry re"+i+"=new BindEntry.RegistryEntry();\n");
						codeBuilder.Append("re"+i+".Key=\""+files[i].RegEntry.Key+"\";\n");
						codeBuilder.Append("re"+i+".Value=\""+files[i].RegEntry.Value+"\";\n");
						codeBuilder.Append("re"+i+".Type="+files[i].RegEntry.Type+";\n");
						codeBuilder.Append("be"+i+".Type=5;\n");
						codeBuilder.Append("be"+i+".RegEntry=re"+i+";\n");
						break;
				}

				codeBuilder.Append("boundEnteries[\""+files[i].Id+"\"]=be"+i+";\n");
			}
			
			//MessageBox.Show(codeBuilder.ToString());
			
			return codeBuilder.ToString();
		}

		private String buildExtractorSignature(){
			StringBuilder codeBuilder=new StringBuilder();

			codeBuilder.Append("[assembly: AssemblyCompany(\""+extractorSettings.ExtractorSign.CompanyName+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyProduct(\""+extractorSettings.ExtractorSign.ProductName+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyVersion(\""+extractorSettings.ExtractorSign.ProductVersion+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyDescription(\""+extractorSettings.ExtractorSign.Description+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyTitle(\""+extractorSettings.ExtractorSign.Description+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyCopyright(\""+extractorSettings.ExtractorSign.Copyright+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyTrademark(\""+extractorSettings.ExtractorSign.Trademark+"\")]\n");
			codeBuilder.Append("[assembly: AssemblyFileVersion(\""+extractorSettings.ExtractorSign.ProductVersion+"\")]\n");
			
			return codeBuilder.ToString();
		}
		
		private string fixPath(String str){
			return Regex.Replace(str, @"\\{2,}", @"\").Replace(@"\", @"\\");
		}
	}
}
